#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');
const { execSync } = require('child_process');

// 动态导入 ES 模块
let chalk;

// 初始化 ES 模块
async function initializeModules() {
  if (!chalk) {
    chalk = (await import('chalk')).default;
  }
}

/**
 * SDAT-Method 的 YAML 格式化和校验工具
 * 格式化并验证 YAML 文件和 Markdown 中嵌入的 YAML
 */

async function formatYamlContent(content, filename) {
  await initializeModules();
  try {
    // 首先尝试修复常见的 YAML 问题
    let fixedContent = content
      // 修复 "commands :" -> "commands:"
      .replace(/^(\s*)(\w+)\s+:/gm, '$1$2:')
      // 修复不一致的列表缩进
      .replace(/^(\s*)-\s{3,}/gm, '$1- ');

    // 跳过 .roomodes 文件的自动修复 - 它们有特殊的嵌套结构
    if (!filename.includes('.roomodes')) {
      fixedContent = fixedContent
        // 修复包含特殊字符或多部分的未引用列表项
        .replace(/^(\s*)-\s+(.*)$/gm, (match, indent, content) => {
          // 如果已经引用则跳过
          if (content.startsWith('"') && content.endsWith('"')) {
            return match;
          }
          // 如果内容包含特殊的 YAML 字符或看起来复杂，则引用它
          // 但如果它看起来像一个正确的 YAML 键值对（如 "key: value"），则跳过
          if ((content.includes(':') || content.includes('-') || content.includes('{') || content.includes('}')) &&
              !content.match(/^\w+:\s/)) {
            // 先删除任何现有的引号，转义内部引号，然后添加适当的引号
            const cleanContent = content.replace(/^["']|["']$/g, '').replace(/"/g, '\\"');
            return `${indent}- "${cleanContent}"`;
          }
          return match;
        });
    }

    // 调试：显示我们尝试解析的内容
    if (fixedContent !== content) {
      console.log(chalk.blue(`🔧 已对 ${filename} 应用 YAML 修复`));
    }

    // 解析并重新转储 YAML 以格式化它
    const parsed = yaml.load(fixedContent);
    const formatted = yaml.dump(parsed, {
      indent: 2,
      lineWidth: -1, // Disable line wrapping
      noRefs: true,
      sortKeys: false // Preserve key order
    });
    return formatted;
  } catch (error) {
    console.error(chalk.red(`❌ ${filename} 中的 YAML 语法错误:`), error.message);
    console.error(chalk.yellow(`💡 尝试先手动修复 YAML 结构`));
    return null;
  }
}

async function processMarkdownFile(filePath) {
  await initializeModules();
  const content = fs.readFileSync(filePath, 'utf8');
  let modified = false;
  let newContent = content;

  // 通过添加 'text' 类型修复无类型代码块
  // 匹配行首的 ``` 后跟换行符，但仅当它是开始分隔符时
  newContent = newContent.replace(/^```\n([\s\S]*?)\n```$/gm, '```text\n$1\n```');
  if (newContent !== content) {
    modified = true;
    console.log(chalk.blue(`🔧 已向 ${filePath} 中的无类型代码块添加 'text' 类型`));
  }

  // 查找 YAML 代码块
  const yamlBlockRegex = /```ya?ml\n([\s\S]*?)\n```/g;
  let match;
  const replacements = [];

  while ((match = yamlBlockRegex.exec(newContent)) !== null) {
    const [fullMatch, yamlContent] = match;
    const formatted = await formatYamlContent(yamlContent, filePath);
    if (formatted !== null) {
      // Remove trailing newline that js-yaml adds
      const trimmedFormatted = formatted.replace(/\n$/, '');

      if (trimmedFormatted !== yamlContent) {
        modified = true;
        console.log(chalk.green(`✓ 已格式化 ${filePath} 中的 YAML`));
      }

      replacements.push({
        start: match.index,
        end: match.index + fullMatch.length,
        replacement: `\`\`\`yaml\n${trimmedFormatted}\n\`\`\``
      });
    }
  }

  // 以相反的顺序应用替换以保持索引
  for (let i = replacements.length - 1; i >= 0; i--) {
    const { start, end, replacement } = replacements[i];
    newContent = newContent.slice(0, start) + replacement + newContent.slice(end);
  }

  if (modified) {
    fs.writeFileSync(filePath, newContent);
    return true;
  }
  return false;
}

async function processYamlFile(filePath) {
  await initializeModules();
  const content = fs.readFileSync(filePath, 'utf8');
  const formatted = await formatYamlContent(content, filePath);

  if (formatted === null) {
    return false; // Syntax error
  }

  if (formatted !== content) {
    fs.writeFileSync(filePath, formatted);
    return true;
  }
  return false;
}

async function lintYamlFile(filePath) {
  await initializeModules();
  try {
    // 使用 yaml-lint 进行额外验证
    execSync(`npx yaml-lint "${filePath}"`, { stdio: 'pipe' });
    return true;
  } catch (error) {
    console.error(chalk.red(`❌ ${filePath} 中的 YAML 校验错误:`));
    console.error(error.stdout?.toString() || error.message);
    return false;
  }
}

async function main() {
  await initializeModules();
  const args = process.argv.slice(2);
  const glob = require('glob');

  if (args.length === 0) {
    console.error('用法: node yaml-format.js <文件1> [文件2] ...');
    process.exit(1);
  }

  let hasErrors = false;
  let hasChanges = false;
  let filesProcessed = [];

  // 展开 glob 模式并收集所有文件
  const allFiles = [];
  for (const arg of args) {
    if (arg.includes('*')) {
      // 这是一个 glob 模式
      const matches = glob.sync(arg);
      allFiles.push(...matches);
    } else {
      // 这是一个直接文件路径
      allFiles.push(arg);
    }
  }

  for (const filePath of allFiles) {
    if (!fs.existsSync(filePath)) {
      // 对不匹配任何内容的 glob 模式静默跳过
      if (!args.some(arg => arg.includes('*') && filePath === arg)) {
        console.error(chalk.red(`❌ 找不到文件: ${filePath}`));
        hasErrors = true;
      }
      continue;
    }

    const ext = path.extname(filePath).toLowerCase();
    const basename = path.basename(filePath).toLowerCase();

    try {
      let changed = false;
      if (ext === '.md') {
        changed = await processMarkdownFile(filePath);
      } else if (ext === '.yaml' || ext === '.yml' || basename.includes('roomodes') || basename.includes('.yaml') || basename.includes('.yml')) {
        // 处理 YAML 文件和特殊情况，如 .roomodes
        changed = await processYamlFile(filePath);

        // 同时运行校验
        const lintPassed = await lintYamlFile(filePath);
        if (!lintPassed) hasErrors = true;
      } else {
        // 对不支持的文件静默跳过
        continue;
      }

      if (changed) {
        hasChanges = true;
        filesProcessed.push(filePath);
      }
    } catch (error) {
      console.error(chalk.red(`❌ 处理 ${filePath} 时出错:`), error.message);
      hasErrors = true;
    }
  }

  if (hasChanges) {
    console.log(chalk.green(`\n✨ YAML 格式化完成！已修改 ${filesProcessed.length} 个文件:`));
    filesProcessed.forEach(file => console.log(chalk.blue(`  📝 ${file}`)));
  }

  if (hasErrors) {
    console.error(chalk.red('\n💥 一些文件有错误。请在提交前修复它们。'));
    process.exit(1);
  }
}

if (require.main === module) {
  main().catch(error => {
    console.error('错误:', error);
    process.exit(1);
  });
}

module.exports = { formatYamlContent, processMarkdownFile, processYamlFile };